﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;


namespace wpfHungryCitizen
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        List<Obstacle> m_StaticPics = new List<Obstacle>();        

        List<Body> m_bolas = new List<Body>();
        Point m_elipse2initialLoc = new Point(0,0);
        AnimationClock m_clock;
        RotateTransform m_rotateEllipse;
        bool m_draga = false;
        DoubleAnimation m_pa;
        DoubleAnimation m_pb;
        TranslateTransform m_moveEll2;
        AnimationClock m_clockElli2;
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            ahh.Stop();
            ahh.Play();
        }
        
        double m_angle = -1;
        DispatcherTimer m_timer = null;
        DispatcherTimer m_timerAnim = null;
        Point velo = new Point(0,0);
        double inercia = .99;
        double gravidade = .4;
        Brush[] m_cores = new Brush[] { Brushes.Black, Brushes.Red, Brushes.Green, Brushes.Blue, Brushes.Yellow };

        private void rectangle2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ButtonState == MouseButtonState.Pressed)
            {
                rectangle1.RenderTransform = new RotateTransform(m_angle -= .5, 20, 120);
                if (m_timer == null)
                {
                    m_timer = new DispatcherTimer();
                    m_timer.Tick += new EventHandler(m_timer_Tick);
                    m_timer = new DispatcherTimer();
                    m_timer.Tick += new EventHandler(m_timer_Tick);
                    m_timer.Interval = TimeSpan.FromMilliseconds(100);
                }
                m_timer.Start();

            }
        }


        void m_timer_Tick(object sender, EventArgs e)
        {
            MouseButtonState ButtonState = Mouse.LeftButton;
            if (  ButtonState == MouseButtonState.Pressed )
            {


            }            
        }


        private void rectangle2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            m_timer.Stop();
        }

        private void rectangle3_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (m_timer == null)
            {
                m_timer = new DispatcherTimer();
                m_timer.Tick += new EventHandler(m_timer_Tick);
                m_timer = new DispatcherTimer();
                m_timer.Tick += new EventHandler(m_timer_Tick);
                m_timer.Interval = TimeSpan.FromMilliseconds(100);
            }
            rectangle1.RenderTransform = new RotateTransform(m_angle += .5, 20, 120);
            //lbAngle.RenderTransform = new RotateTransform(m_angle += .5, -15, -50);
            m_timer.Start();

        }

        private void rectangle3_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            m_timer.Stop();
        }


        private void ellipse1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (m_timer == null)
            {
                m_timer = new DispatcherTimer();
                m_timer.Tick += new EventHandler(m_timer_Tick);
                m_timer = new DispatcherTimer();
                m_timer.Tick += new EventHandler(m_timer_Tick);
                m_timer.Interval = TimeSpan.FromMilliseconds(100);
            }
            m_timer.Start();
            velo.X++;
            velo.Y++;
        }

        private void ellipse1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            //m_timer.Stop();
            Random rdCores = new Random(DateTime.Now.Millisecond);

            double X = m_elipse2initialLoc.X - ellipse2.Width/2 ;
            double Y = m_elipse2initialLoc.Y - ellipse2.Height/2;
            Point newPoint = rectangle1.TranslatePoint(new Point(X, Y), canvas1   );
            //newPoint = rectangle1.TranslatePoint(newPoint, canvas1);
            X = newPoint.X;
            Y = newPoint.Y;
            Ellipse bol = new Ellipse();
            bol.Width = 20;
            bol.Height = 20;
            bol.Name = "L" + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString();
            bol.Fill = ellipse2.Fill;
            ellipse2.Fill = m_cores[rdCores.Next(m_cores.Length)];
            canvas1.Children.Add(bol);
            Canvas.SetLeft(bol, X);
            Canvas.SetTop(bol, Y);
            // m_bolas.Add(new Bola(new Point(velo, -velo * Math.Tan((-m_angle + 48) / 180 * Math.PI)), bol));
            m_bolas.Add(new Body(velo, bol));
            //gunFire.Stop();
            //gunFire.Play();
            gunFirePlay();
            if (m_timerAnim == null)
            {
                m_timerAnim = new DispatcherTimer();
                m_timerAnim.Interval = TimeSpan.FromMilliseconds(33);
                m_timerAnim.Tick += new EventHandler(m_timerAnim_Tick);
                m_timerAnim.IsEnabled = true;
            }
            m_timerAnim.Start();
            velo = new Point(0,0);
        }

        void m_timerAnim_Tick(object sender, EventArgs e)
        {
            MoveObj();
        }
        void MoveObj()
        {
            label1.Content = string.Format("{0:hh:mm:ss,ff}", DateTime.Now);
            List<Point> lstPoints = new List<Point>();
            foreach (Body b in m_bolas)
            {
                Shape ctr = b.ctr as Shape;
                Random rd = new Random(DateTime.Now.Millisecond);
                double X = Canvas.GetLeft(ctr); //RenderedGeometry.Transform. GetRenderBounds(new Pen(Brushes.Black, 1F));    
                X = X + b.velo.X;                
                double Y = Canvas.GetTop(ctr);
                Y = Y + b.velo.Y;
                // Lookup any closer bola or object
                Body bolaColide = m_bolas.Find(delegate(Body bl)
                {
                    Shape ctl = bl.ctr as Shape;
                    if (ctr.Name == ctl.Name)
                        return false;
                    double p = Canvas.GetLeft(ctl) + ctl.Width /2 ;
                    double q = Canvas.GetTop(ctl) + ctl.Height /2;
                    double a = Math.Abs(Math.Abs(p) - Math.Abs(X + ctr.Width /2) );
                    double c = Math.Abs(Math.Abs(q) - Math.Abs(Y + ctr.Height/2) );

                    bool res1 = a < (ctr.Width + ctl.Width)/2  && c < (ctr.Height + ctl.Height )/2;
                    bool res2 = false;
                    Obstacle colidiu = null;
                    foreach (Obstacle item in m_StaticPics )
                    {
                         res2 = getHitingObstacle(new Point(p,q) , item.edges.ToArray(), 5);
                         if (res2)
                         {
                             spreadRcPics(item.rectangles.ToArray());
                             colidiu = item;
                         }
                    }
                    if(colidiu != null)
                        m_StaticPics.Remove(colidiu);
                    return res1 || res2;
                });
                if (bolaColide != null)
                {
                    //b.colisoes++;
                    if (b.colisoes > 3)
                    {
                        continue;
                    }
                    b.velo.X = -1 * Math.Sign(b.velo.Y) * rd.Next(1, 10);
                    b.velo.Y = -1 * Math.Sign(b.velo.Y) * rd.Next(1, 10);
                    bolaColide.velo.X = -1 * Math.Sign(bolaColide.velo.Y) * rd.Next(1, 10);
                    bolaColide.velo.Y = -1 * Math.Sign(bolaColide.velo.Y) * rd.Next(1, 10);
                    if ((bolaColide.ctr as Shape).Name == "miguis")
                    {
                        m_rotateEllipse = new RotateTransform(0, 30, 30);
                        (bolaColide.ctr as Shape).RenderTransform = m_rotateEllipse;
                        DoubleAnimation myAnimation =
                        new DoubleAnimation(
                            1, // "From" value
                            1200, // "To" value 
                            new Duration(TimeSpan.FromSeconds(2))
                        );
                        myAnimation.AutoReverse = true;
                        myAnimation.DecelerationRatio = .2;
                        myAnimation.AccelerationRatio = .2;
                        m_clock = myAnimation.CreateClock();
                        m_rotateEllipse.ApplyAnimationClock(RotateTransform.AngleProperty, m_clock);
                        //ahh.Stop();
                        //ahh.Play();
                        ahhPlay();
                        if(bolaColide.velo.X == 0 || bolaColide.velo.Y == 0)
                            bolaColide.velo = new Point(rd.Next(5,10), - rd.Next(5,10));
                    }
                }
                if (X < 1)
                {
                    b.velo.X = rd.Next(1, 10);
                    b.velo.Y = Math.Sign(b.velo.Y) * rd.Next(1, 10);
                    //b.colisoes++;
                }
                if (X > (canvas1.ActualWidth - 20))
                {

                    b.velo.X = -1 * rd.Next(1, 10);
                    b.velo.Y = Math.Sign(b.velo.Y) * rd.Next(1, 10);
                    //b.colisoes++;
                }
                if (Y < 1)
                {
                    b.velo.X = Math.Sign(b.velo.X) * rd.Next(1, 10);
                    b.velo.Y = rd.Next(1, 10);
                    //b.colisoes++;
                }
                if (Y > (canvas1.ActualHeight - 20))
                {
                    b.velo.X = Math.Sign(b.velo.X) * rd.Next(1, 10);
                    b.velo.Y = -1 * rd.Next(1, 10);
                    b.colisoes++;
                }
                // do move
                if (!ctr.Name.StartsWith("p"))
                {
                    Canvas.SetLeft(ctr, X);
                    Canvas.SetTop(ctr, Y);
                    b.velo.X *= inercia;
                    b.velo.Y = b.velo.Y * inercia + ((b.ctr as Shape).Name != "miguis" ? gravidade : 0);
                    lstPoints.Add(new Point(X, Y));
                }
            }
            //clean colisoes
            List<Body> lstBola = new List<Body>();
            for (int ix = 0; ix < m_bolas.Count; ix++)
            {

                if (m_bolas[ix].colisoes <= 3 || (m_bolas[ix].ctr as Shape).Name == "miguis" || (m_bolas[ix].ctr as Shape).Name.StartsWith("p"))
                    lstBola.Add(m_bolas[ix]);
                else
                {
                    canvas1.Children.Remove(m_bolas[ix].ctr as Shape);
                    //pum.Stop();
                    //pum.Play();
                    pumPlay();
                    //if (m_StaticPics.Count > 0)
                    //{
                    //    spreadRcPics(m_StaticPics[m_StaticPics.Count - 1].rectangles.ToArray());
                    //    m_StaticPics.RemoveAt(m_StaticPics.Count - 1);

                    //}
                }
            }
            m_bolas = lstBola;
        }

        private void miguis_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            m_bolas.Add(new Body(new Point(0, 0), miguis));
            m_bolas.Add (new Body(new Point(0, 0),p1));
            m_bolas.Add (new Body(new Point(0, 0),p2));
            m_bolas.Add (new Body(new Point(0, 0),p3));
            m_bolas.Add (new Body(new Point(0, 0),p4));
            Random rnd = new Random(DateTime.Now.Millisecond);
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/dILMA01.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock01.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock02.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock03.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock01.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock02.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock03.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock01.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock02.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/Rock03.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/mig01.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/gun011.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));
            AddPicStamp("pack://application:,,,/wpfHungryCitizen;component/Images/greenLarrow.gif", new Point(rnd.Next((int)this.Width), rnd.Next((int)this.Height)));

        }


        private void ahhPlay()
        {
            System.IO.Stream st = this.GetType().Assembly.GetManifestResourceStream("wpfHungryCitizen.Media.bd24260.wav");
            System.Media.SoundPlayer sp = new System.Media.SoundPlayer(st);
            sp.Play();

        }
        private void pumPlay()
        {
            object oo = this.Resources["pum"];
            System.IO.Stream st = this.GetType().Assembly.GetManifestResourceStream("/wpfHungryCitizen/Media/bangbang.wav");
            System.Media.SoundPlayer sp = new System.Media.SoundPlayer(st);
            sp.Play();

        }
        private void gunFirePlay()
        {
            System.IO.Stream st = this.GetType().Assembly.GetManifestResourceStream("wpfHungryCitizen.Media.gunfire.wav");
            System.Media.SoundPlayer sp = new System.Media.SoundPlayer(st);
            sp.Play();

        }

        private void rectangle5_Loaded(object sender, RoutedEventArgs e)
        {
            line1.X1 = Canvas.GetLeft(rectangle5);
            line1.Y1 = Canvas.GetTop(rectangle5);
            line1.X2 = Canvas.GetLeft(ellipse2) + ellipse2.Width / 2;
            line1.Y2 = Canvas.GetTop(ellipse2) + ellipse2.Height / 2;
            m_elipse2initialLoc = new Point(line1.X2, line1.Y2);
            line2.X1 = Canvas.GetLeft(rectangle5) + rectangle5.Width;
            line2.Y1 = Canvas.GetTop(rectangle5);
            line2.X2 = Canvas.GetLeft(ellipse2) + ellipse2.Width / 2;
            line2.Y2 = Canvas.GetTop(ellipse2) + ellipse2.Height / 2;
        }

        private void ellipse2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //m_elipse2initialLoc = new Point( Canvas.GetLeft(ellipse2), Canvas.GetTop(ellipse2)) ;
            ellipse2.RenderTransform = null;
            m_draga = true;
        }

        private void ellipse2_MouseMove(object sender, MouseEventArgs e)
        {
        }

        private void ellipse2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            m_draga = false;
            double X = e.GetPosition(rectangle1).X - Canvas.GetLeft(ellipse2) - ellipse2.Width /2;
            double Y = e.GetPosition(rectangle1).Y - Canvas.GetTop(ellipse2) - ellipse2.Height /2;
            double Xo = m_elipse2initialLoc.X;
            double Yo = m_elipse2initialLoc.Y;
            m_moveEll2 = new TranslateTransform(X, Y);
            ellipse2.RenderTransform = m_moveEll2;
            m_pa = new DoubleAnimation( X, m_elipse2initialLoc.X - Canvas.GetLeft(ellipse2) - ellipse2.Width /2, TimeSpan.FromMilliseconds(200));
            m_pb = new DoubleAnimation(Y, m_elipse2initialLoc.Y - Canvas.GetTop(ellipse2) - ellipse2.Height /2, TimeSpan.FromMilliseconds(200));
            
            m_clockElli2 = m_pa.CreateClock();
            AnimationClock ancl2 = m_pb.CreateClock();
            m_moveEll2.ApplyAnimationClock(TranslateTransform.XProperty, m_clockElli2);
            m_moveEll2.ApplyAnimationClock(TranslateTransform.YProperty, ancl2);
            m_clockElli2.Completed += new EventHandler(m_clockElli2_Completed);
            Point mo = Mouse.GetPosition(rectangle1);
            velo.X = ( m_elipse2initialLoc.X -mo.X) / 5;
            velo.Y = -(mo.Y - m_elipse2initialLoc.Y ) / 5;

        }
        void m_clockElli2_Completed(object sender, EventArgs e)
        {
            line1.X1 = Canvas.GetLeft(rectangle5);
            line1.Y1 = Canvas.GetTop(rectangle5);
            line1.X2 =  m_elipse2initialLoc.X; 
            line1.Y2 = m_elipse2initialLoc.Y;
            line2.X1 = Canvas.GetLeft(rectangle5) + rectangle5.Width;
            line2.Y1 = Canvas.GetTop(rectangle5);
            line2.X2 = m_elipse2initialLoc.X ;
            line2.Y2 = m_elipse2initialLoc.Y ;
            ellipse1_MouseLeftButtonUp(sender, new MouseButtonEventArgs(Mouse.PrimaryDevice , 100, MouseButton.Left ));
        }
        private void rectangle1_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_draga)
            {
                Canvas.SetLeft(ellipse2, e.GetPosition(rectangle1).X - ellipse2.Width /2);
                Canvas.SetTop(ellipse2, e.GetPosition(rectangle1).Y - ellipse2.Height /2);
                line1.X1 = Canvas.GetLeft(rectangle5);
                line1.Y1 = Canvas.GetTop(rectangle5);
                line1.X2 = Canvas.GetLeft(ellipse2) + ellipse2.Width /2;
                line1.Y2 = Canvas.GetTop(ellipse2) + ellipse2.Height /2;
                line2.X1 = Canvas.GetLeft(rectangle5) + rectangle5.Width;
                line2.Y1 = Canvas.GetTop(rectangle5);
                line2.X2 = Canvas.GetLeft(ellipse2) + ellipse2.Width/2;
                line2.Y2 = Canvas.GetTop(ellipse2) + ellipse2.Height /2;
            }

        }

        private void rectangle1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            m_draga = false;
            ellipse2_MouseLeftButtonUp(sender, e);
        }

        private void rectangle1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Canvas.SetLeft(ellipse2, e.GetPosition(rectangle1).X + ellipse2.Width/2);
            Canvas.SetTop(ellipse2, e.GetPosition(rectangle1).Y + ellipse2.Height/2);
        }

        private void button1_Click_1(object sender, RoutedEventArgs e)
        {
            Window3  frm = new Window3();
            frm.Show();
        }
        /// <summary>
        /// Quadricula uma foto e adiciona ao Canvas
        /// </summary>
        /// <param name="resur"></param>
        private void AddPicStamp(string resur, Point p)
        {
            int m_h_ctr = 0;
            Rect rDestin = new Rect(p, new Size(4, 4));

            //pack://application:,,,/wpfPUM;component/Images/Rock02.gif
            //pack://application:,,,/wpfPUM;component/Images/Rock03.gif

            BitmapImage bm = new BitmapImage(new Uri(resur));
            TransformedBitmap tfbmp = new TransformedBitmap(bm, new ScaleTransform(.3, .3));


            //Int32Rect rrr = bm.SourceRect ;
            //br.ImageSource = new BitmapImage(new Uri(@"Images\Rock03.gif"), new System.Net.Cache.RequestCachePolicy());
            int cols = (int)(tfbmp.Width / rDestin.Width);
            int rows = (int)(tfbmp.Height / rDestin.Height);
            List<Rectangle> lstRects = new List<Rectangle>();
            List<Point> lstPoints = new List<Point>();
            for (m_h_ctr = 0; m_h_ctr < rows; m_h_ctr++)
            {
                Point? left = null;
                Point? right = null;

                for (int i = 0; i < cols; i++)
                {
                    Rectangle rtgPic = new Rectangle();
                    rtgPic.Height = rDestin.Height;
                    rtgPic.Width = rDestin.Width;
                    ImageBrush br = new ImageBrush();
                    CroppedBitmap crps = new CroppedBitmap(tfbmp, new Int32Rect(i * (int)rtgPic.Width, m_h_ctr * (int)rtgPic.Height, (int)rtgPic.Width, (int)rtgPic.Height));
                    br.ImageSource = crps;
                    int[] iqs = new int[(int)rtgPic.Width * (int)rtgPic.Height * crps.Format.BitsPerPixel * crps.Format.BitsPerPixel];

                    crps.CopyPixels(iqs, 64, 0);
                    int sum = isBlack(iqs);
                    rtgPic.Fill = br;
                    //rtgPic.Stroke = Brushes.Black;
                    //rtgPic.StrokeThickness = 0.1;
                    Point loc = new Point(p.X + i * rtgPic.Width, p.Y + m_h_ctr * rtgPic.Height);
                    double x = (double)rtgPic.GetValue(Canvas.LeftProperty);
                    //loc = rtg.TranslatePoint(new Point(loc.X - x, 0), m_cc);
                    rtgPic.SetValue(Canvas.LeftProperty, loc.X);
                    rtgPic.SetValue(Canvas.TopProperty, loc.Y);
                    if (sum != 0)
                    {
                        canvas1.Children.Add(rtgPic);
                        lstRects.Add(rtgPic);
                        if (left == null)
                            left = new Point(loc.X, loc.Y);
                        right = new Point(loc.X, loc.Y);
                    }
                }
                if(left != null)
                    lstPoints.Add(left as Point? ?? new Point(0,0));
                if(right != null)
                    lstPoints.Add(right as Point? ?? new Point(0,0));
            }
            
            m_StaticPics.Add(new Obstacle(lstRects, lstPoints));
        }
        /// <summary>
        /// calculate the sum of array's elems (pixels)
        /// </summary>
        /// <param name="iq"></param>
        /// <returns>0 means black</returns>
        private int isBlack(int[] iq)
        {
            int sum = 0;
            foreach (var o in iq)
            {
                sum += o;
            }
            return sum;
        }
        int m_ctr = 0;
        void spreadRcPics(Rectangle[] children)
        {
            
            Random rd = new Random(DateTime.Now.Millisecond);
            foreach (UIElement ele in children)
            {
                Storyboard sb = new Storyboard();
                Shape xa = ele as Shape;

                double va = 100 - rd.Next(200);
                DoubleAnimation leftAnim = moveLeft(ele as Shape, va);
                Storyboard.SetTargetName(ele, (ele as Shape).Name);
                Storyboard.SetTargetProperty(leftAnim, new PropertyPath(Canvas.LeftProperty));
                va = 100 - rd.Next(200);
                Storyboard.SetTargetName(ele, (ele as Shape).Name);
                DoubleAnimation topAnim = moveTop(ele as Shape, va);
                Storyboard.SetTargetProperty(topAnim, new PropertyPath(Canvas.TopProperty));
                va = rd.Next(1200);
                DoubleAnimation tm = rotate(ele as Shape, va);
                //Storyboard.SetTargetName(ele, (ele as Shape).Name);
                //Storyboard.SetTargetProperty(tm, new PropertyPath( RotateTransform.AngleProperty));

                RotateTransform rtf = new RotateTransform(85);

                xa.RenderTransform = rtf;
                rtf.CenterX = 8;
                rtf.CenterY = 8;
                RegisterName(xa.Name + "m" + m_ctr.ToString(), rtf);
                Storyboard.SetTargetName(tm, xa.Name + "m" + m_ctr.ToString());
                m_ctr++;
                Storyboard.SetTargetProperty(tm, new PropertyPath(RotateTransform.AngleProperty));
                //dismiss rect
                DoubleAnimation shade = new DoubleAnimation(100, 0, new Duration( TimeSpan.FromSeconds (1.5)), FillBehavior.HoldEnd);
                Storyboard.SetTargetProperty(shade, new PropertyPath(Rectangle.OpacityProperty));

                sb.Children.Add(shade);
                sb.Children.Add(leftAnim);
                sb.Children.Add(topAnim);
                sb.Children.Add(tm);
                //xa.BeginStoryboard(sb);               
                sb.Begin(xa);
            }
        }
        DoubleAnimation shade(Shape obj)
        {

            DoubleAnimation myAnimation =
            new DoubleAnimation(
                100, // "From" value
                0, // "To" value 
                new Duration(TimeSpan.FromSeconds(3))
            );
            return myAnimation;
        }
        DoubleAnimation moveLeft(Shape obj, double va)
        {
            TranslateTransform moveShape = new TranslateTransform(0, 0);
            (obj as Shape).RenderTransform = moveShape;
            double x = obj.GetValue(Canvas.LeftProperty) as double? ?? 0;
            DoubleAnimation myAnimation =
            new DoubleAnimation(
                x, // "From" value
                x + va, // "To" value 
                new Duration(TimeSpan.FromSeconds(3))
            );
            myAnimation.AutoReverse = false;
            myAnimation.FillBehavior = FillBehavior.HoldEnd;
            myAnimation.EasingFunction = new ElasticEase();// new BounceEase();
            myAnimation.DecelerationRatio = .2;
            myAnimation.AccelerationRatio = .2;
            ;
            //AnimationClock clock = myAnimation.CreateClock();
            //moveShape.ApplyAnimationClock(TranslateTransform.XProperty, clock, HandoffBehavior.Compose);
            //moveShape.BeginAnimation(Canvas.LeftProperty, myAnimation, HandoffBehavior.Compose);
            //Storyboard.SetTargetProperty(Canvas.LeftProperty, new PropertyPath());
            return myAnimation;
        }
        DoubleAnimation moveTop(Shape obj, double va)
        {
            double y = obj.GetValue(Canvas.TopProperty) as double? ?? 0;
            TranslateTransform moveShape = new TranslateTransform(0, 0);
            (obj as Shape).RenderTransform = moveShape;
            DoubleAnimation myAnimation =
            new DoubleAnimation(
                y, // "From" value
                y + va, // "To" value 
                new Duration(TimeSpan.FromSeconds(3))
            );
            myAnimation.AutoReverse = false;
            myAnimation.FillBehavior = FillBehavior.HoldEnd;
            myAnimation.EasingFunction = new ElasticEase();// new BounceEase();
            myAnimation.DecelerationRatio = .2;
            myAnimation.AccelerationRatio = .2;
            //AnimationClock clock = myAnimation.CreateClock();
            //moveShape.ApplyAnimationClock(TranslateTransform.YProperty, clock, HandoffBehavior.Compose);
            //moveShape.BeginAnimation(Canvas.TopProperty, myAnimation, HandoffBehavior.Compose);
            return myAnimation;
        }
        DoubleAnimation rotate(Shape obj, double va)
        {
            RotateTransform moveShape = new RotateTransform(va);
            (obj as Shape).RenderTransform = moveShape;
            DoubleAnimation myAnimation =
            new DoubleAnimation(
                1, // "From" value
                va, // "To" value 
                new Duration(TimeSpan.FromSeconds(7))
            );

            myAnimation.AutoReverse = false;
            myAnimation.FillBehavior = FillBehavior.HoldEnd;
            myAnimation.EasingFunction = new ElasticEase();// new BounceEase();
            myAnimation.DecelerationRatio = .2;
            myAnimation.AccelerationRatio = .2;
            //AnimationClock clock = myAnimation.CreateClock();
            //moveShape.ApplyAnimationClock(   .BeginAnimation ( , myAnimation, HandoffBehavior.Compose );
            return myAnimation;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="recPicts"></param>
        /// <returns></returns>
        [Obsolete]
        List<Point> getBoundaries(Rectangle[] recPicts)
        {
            List<Point> lstRect = new List<Point>();
            for (int ix=0; ix < recPicts.Length; ix++)
            {
                Rectangle rr = recPicts[ix];
                if (true)
                {
                    lstRect.Add(new Point(0,0));
                }
            }
            return lstRect;
        }
        /// <summary>
        /// true if target is minDistance from edges
        /// </summary>
        /// <param name="target"></param>
        /// <param name="edges"></param>
        /// <param name="minDistance"></param>
        /// <returns></returns>
        bool getHitingObstacle(Point target, Point[] edges, int minDistance)
        {
            foreach (Point edge in edges)
            {
                Vector vc = Point.Subtract(edge, target);
                if (vc.Length <= minDistance)
                    return true;
            }
            return false;
        }

    }
    /// <summary>
    /// Defines moving objects
    /// </summary>
    class Body
    {

        public Point velo;
        public object ctr;
        public int colisoes;
        public Body(Point _velo, Shape _ctr)
        {
            velo = _velo;
            ctr = _ctr;
            colisoes = 0;
        }
    }
    class Obstacle
    {
        public List<Point> edges;
        public List<Rectangle> rectangles;
        public Obstacle()
        {
            edges = new List<Point>();
            rectangles = new List<Rectangle>();
        }
        public Obstacle(List<Rectangle> _rectangles, List<Point> _edges)
        {
            edges = _edges;
            rectangles = _rectangles;
        }
        
    }
}
